package com.wanxi.service.Impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wanxi.dto.ResultDto;
import com.wanxi.mapper.UserMapper;
import com.wanxi.model.UserModel;
import com.wanxi.service.UserService;
import com.wanxi.util.JwtUtil;
import com.wanxi.util.MD5;
import com.wanxi.util.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author Li
 * @Date 2023/7/6 15:06
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserModel> implements UserService {
    @Autowired
    UserMapper userMapper;
    @Autowired
    private AuthenticationManager authenticationManager;

    //    @Autowired
//    private RoleMapper roleMapper;
    @Autowired
    private RedisCache redisCache;

    /**
     * 登录逻辑
     * 1.先判断验证码是否相同
     * 2.把密码加密
     * 3.查询数据库，匹对密码和用户名是否正确，返回结果
     * 4.判断是否登录
     *
     * @param userModel
     * @return
     */
    @Override
    public ResultDto login(UserModel userModel) {
        if (!userModel.getCode().equals(userModel.getVCode())) {
            return ResultDto.builder()
                    .code(0)
                    .msg("error-code")
                    .build();
        }
        //将获取到的前端密码进行加密
//        userModel.setPassword(MD5.encoderByMd5(userModel.getPassword()));
//        UserModel isHave = userMapper.findNameAndPass(userModel);
//        if (isHave == null) {
//            return ResultDto.builder()
//                    .code(0)
//                    .msg("error")
//                    .build();
//        }
        //        AuthenticationManager authenticate进行用户认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userModel.getUsername(), userModel.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
//        如果认证没通过，给出对应提示
        if (Objects.isNull(authenticate)) {
//            throw new RuntimeException("登录失败！");
            return ResultDto.builder()
                    .code(0)
                    .msg("error")
                    .build();

        }
//        认证通过了，使用userid生产一个jwt,将jwt存入ResultDto
        UserModel user = (UserModel) authenticate.getPrincipal();
        String userId = user.getId().toString();
        String jwt = JwtUtil.createJWT(userId);
        Map<String, String> map = new HashMap<>();
        map.put("token", jwt);

//        把完整的用户信息存入rides中，userid为key
        redisCache.setCacheObject("login:" + userId, user);

        return new ResultDto(0, "success", map);

    }

    /**
     * 添加数据
     *
     * @param model
     * @return
     */
    @Override
    public ResultDto add(UserModel model) {
//       增加用户先判断用户名是否已存在，若存在则添加失败,不存在再进行密码加密，添加用户
        UserModel same = userMapper.findSameName(model);
        if (same != null) {
            return ResultDto.builder()
                    .code(0)
                    .msg("用户名已存在")
                    .build();
        }
        UserModel samePhone = userMapper.findSamePhone(model);
        if (samePhone != null) {
            return ResultDto.builder()
                    .code(0)
                    .msg("电话号已存在")
                    .build();
        }
        UserModel sameEmail = userMapper.findSameEmail(model);
        if (sameEmail != null) {
            return ResultDto.builder()
                    .code(0)
                    .msg("邮箱已存在")
                    .build();
        }
        model.setPassword(MD5.encoderByMd5(model.getPassword()));
        //返回代码信息，数据条数
        userMapper.insert(model);
        return ResultDto.builder()
                .code(0)
                .msg("添加成功")
                .build();
    }


    /**
     * 修改密码
     *
     * @param userModel
     * @return
     */
    @Override
    public ResultDto updatePassword(UserModel userModel) {
        userModel.setPassword(MD5.encoderByMd5(userModel.getPassword()));
        userMapper.updatePassword(userModel);
        return ResultDto.builder()
                .code(0)
                .msg("修改成功")
                .build();
    }

    /**
     * 重置密码
     *
     * @param userModel
     * @return
     */
    @Override
    public ResultDto resetPassword(UserModel userModel) {
        userMapper.resetPassword(userModel);
        return ResultDto.builder()
                .code(0)
                .msg("重置成功")
                .build();
    }

    @Override
    public ResultDto loginOut() {
        //从SecurityContextHolder中获取user的id
        UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        //获取到用户对象
        UserModel user = (UserModel) authenticationToken.getPrincipal();
        //得到user的id
        Long userId = user.getId();
        //删除Redis中值
        redisCache.deleteObject("login:" + userId);
        return new ResultDto(0, "退出成功！");
    }


}
